package cn.zlj.nmcc.service.impl;

import cn.zlj.nmcc.constants.BaseConstants;
import cn.zlj.nmcc.domain.*;
import cn.zlj.nmcc.dto.RedisDto;
import cn.zlj.nmcc.dto.RegisterDto;
import cn.zlj.nmcc.exception.GlobalExceptionCodeEnum;
import cn.zlj.nmcc.fegin.LoginService;
import cn.zlj.nmcc.mapper.UserMapper;
import cn.zlj.nmcc.result.JSONResult;
import cn.zlj.nmcc.service.*;
import cn.zlj.nmcc.util.AssertUtil;
import cn.zlj.nmcc.util.BitStatesUtils;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author zlj
 * @since 2022-11-17
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
     @Autowired
     private RedisTemplate<Object,Object> redisTemplate;
     @Autowired
     private LoginService loginService;
     @Autowired
      private IUserService userService;
     @Autowired
     private IUserBaseInfoService userBaseInfoService;
     @Autowired
     private IUserAccountService userAccountService;
     @Autowired
     private ICodeService codeService;
     @Autowired
     private ITjService tjService;
    @Override
    //@Transactional
    @GlobalTransactional(rollbackFor = Exception.class)
    public void smsRegister(RegisterDto registerDto) {
       //参数校验
        //短信验证码是否正确或存在
        String key=String.format(BaseConstants.VerifyCodeConstants.REGISTER_send_SmsCode,registerDto.getMobile());
        Object o = redisTemplate.opsForValue().get(key);
        AssertUtil.isNotNull(o,GlobalExceptionCodeEnum.UAA_YZM_IS_exists);
        RedisDto rd= (RedisDto) o;
        AssertUtil.isEquals(rd.getCode(), registerDto.getSmsCode(),GlobalExceptionCodeEnum.USER_PHONE_WR_NULL);
        //是否被注册
        extracted(registerDto);
        //保存login信息,使用openf uaa 返回loginid
        JSONResult jsonResult = saveLogin(registerDto);
        // 判断服务方是否熔断，如果熔断那么就是服务不可用
        AssertUtil.isTrue(jsonResult.isSuccess(), GlobalExceptionCodeEnum.SERVICE_ERROR);
          //int a=1/0;
        // 判断是否保存成功，如果成功那么data中有loginId
        AssertUtil.isNotNull(jsonResult.getData(), GlobalExceptionCodeEnum.USER_LOGIN_ERROR);
        Long loginId = Long.valueOf(jsonResult.getData().toString());

        User saveUser = saveUser(loginId, registerDto);
        AssertUtil.isNotNull(saveUser.getId(), GlobalExceptionCodeEnum.USER_LOGIN_ERROR);
        extracted(registerDto, saveUser);
        initUserAccount(saveUser.getId());
        initUserBaseInfo(saveUser.getId(), registerDto);
    }

    private void extracted(RegisterDto registerDto, User saveUser) {
        String code = registerDto.getCode();
        Wrapper<Code> wrap=new EntityWrapper<>();
        wrap.eq("code",code);
        Code one = codeService.selectOne(wrap);
        AssertUtil.isNotNull(one,GlobalExceptionCodeEnum.SERVER_PARAM_IS_NULL);

        Tj tj = new Tj();
        tj.setBtjId(saveUser.getId());
        tj.setTjId(one.getUserId());

        tjService.insert(tj);
    }

    private void extracted(RegisterDto registerDto) {
        Wrapper<User> wrapper=new EntityWrapper<>();
        wrapper.eq("phone", registerDto.getMobile());
        User user = userService.selectOne(wrapper);
        AssertUtil.isNull(user,GlobalExceptionCodeEnum.USER_PARAM_IS_exists);
    }

    private void initUserBaseInfo(Long userId, RegisterDto smsRegisterDto) {
        UserBaseInfo userBaseInfo = new UserBaseInfo();
        userBaseInfo.setId(userId);
        userBaseInfo.setCreateTime(new Date().getTime());
        userBaseInfo.setRegChannel(smsRegisterDto.getRegChannel());
        userBaseInfoService.insert(userBaseInfo);
    }

    private void initUserAccount(Long userId) {
        UserAccount userAccount = new UserAccount();
        userAccount.setId(userId);
        userAccount.setCreateTime(new Date().getTime());
        // 此处成功发送邮件告知用户初始支付密码
        userAccount.setPassword("123456");
        userAccountService.insert(userAccount);
    }


    private User saveUser(Long loginId, RegisterDto smsRegisterDto) {
        User user = new User();
        user.setLoginId(loginId);
        user.setCreateTime(new Date().getTime());
        user.setPhone(smsRegisterDto.getMobile());
        user.setNickName(smsRegisterDto.getMobile());
        Long l = BitStatesUtils.addState(BitStatesUtils.OP_ACTIVED,BitStatesUtils.OP_REGISTED);
        l=BitStatesUtils.addState(l,BitStatesUtils.OP_AUTHED_PHONE);
        user.setBitState(l);
        insert(user);
        return user;
    }


    private JSONResult saveLogin(RegisterDto registerDto) {
        Login login = new Login();
        login.setUsername(registerDto.getMobile());
        login.setPassword(registerDto.getPassword());
        return loginService.saveOrUpdate(login);
    }

}
